{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "%matplotlib inline\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "class mymodule(torch.nn.Module):\n",
    "  def __init__(self):\n",
    "    super(mymodule, self).__init__()\n",
    "    self.a = nn.Parameter(torch.randn(1))\n",
    "    self.a.require_grad = True\n",
    "    self.b = nn.Parameter(torch.randn(1))\n",
    "    self.b.requires_grad = True\n",
    "\n",
    "  def forward(self, x):\n",
    "    y = x * self.a + self.b \n",
    "    return y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "input_list = np.sort(np.random.randn(100))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "output_list = 3 * input_list + 20 + np.random.randn(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 画图观察\n",
    "plt.plot(input_list, output_list, color=\"r\", linestyle=\"--\", marker=\"*\", linewidth=1.0)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_run = mymodule()\n",
    "\n",
    "# 定义损失函数和优化器\n",
    "import torch.optim as opt\n",
    "\n",
    "loss_fn = nn.CrossEntropyLoss()\n",
    "opt_fn = opt.SGD(test_run.parameters(), lr=0.001, momentum=0.9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-2.187948018453601\n",
      "cur_y: 14.641382\n",
      "tensor([1.1836], grad_fn=<PowBackward0>)\n",
      "-1.7405125508198236\n",
      "cur_y: 13.517009\n",
      "tensor([1.8534], grad_fn=<PowBackward0>)\n",
      "-1.6161050508794292\n",
      "cur_y: 14.206617\n",
      "tensor([1.0670], grad_fn=<PowBackward0>)\n",
      "-1.539434640381596\n",
      "cur_y: 15.724416\n",
      "tensor([0.0732], grad_fn=<PowBackward0>)\n",
      "-1.531441246260783\n",
      "cur_y: 16.121308\n",
      "tensor([0.4260], grad_fn=<PowBackward0>)\n",
      "-1.4537666913906526\n",
      "cur_y: 15.134126\n",
      "tensor([0.3152], grad_fn=<PowBackward0>)\n",
      "-1.4173733580852041\n",
      "cur_y: 16.818831\n",
      "tensor([1.0439], grad_fn=<PowBackward0>)\n",
      "-1.4095521638417208\n",
      "cur_y: 15.819145\n",
      "tensor([2.4462e-06], grad_fn=<PowBackward0>)\n",
      "-1.31428470331877\n",
      "cur_y: 17.836585\n",
      "tensor([3.0002], grad_fn=<PowBackward0>)\n",
      "-1.301434359224939\n",
      "cur_y: 16.280937\n",
      "tensor([0.0165], grad_fn=<PowBackward0>)\n",
      "-1.1223677165321995\n",
      "cur_y: 18.041495\n",
      "tensor([1.8172], grad_fn=<PowBackward0>)\n",
      "-1.0641820967729545\n",
      "cur_y: 16.927835\n",
      "tensor([0.0023], grad_fn=<PowBackward0>)\n",
      "-1.0413133304271038\n",
      "cur_y: 17.663022\n",
      "tensor([0.4944], grad_fn=<PowBackward0>)\n",
      "-0.9962885940327544\n",
      "cur_y: 18.278264\n",
      "tensor([1.3724], grad_fn=<PowBackward0>)\n",
      "-0.9567895764979094\n",
      "cur_y: 17.492740\n",
      "tensor([0.0639], grad_fn=<PowBackward0>)\n",
      "-0.9042935499967484\n",
      "cur_y: 17.285951\n",
      "tensor([0.0154], grad_fn=<PowBackward0>)\n",
      "-0.898345171592157\n",
      "cur_y: 15.501333\n",
      "tensor([3.7622], grad_fn=<PowBackward0>)\n",
      "-0.8783769844499809\n",
      "cur_y: 17.131412\n",
      "tensor([0.1392], grad_fn=<PowBackward0>)\n",
      "-0.8447970382011947\n",
      "cur_y: 16.154646\n",
      "tensor([2.1062], grad_fn=<PowBackward0>)\n",
      "-0.7975396113765533\n",
      "cur_y: 18.603460\n",
      "tensor([0.7422], grad_fn=<PowBackward0>)\n",
      "-0.78700806407284\n",
      "cur_y: 17.055384\n",
      "tensor([0.5160], grad_fn=<PowBackward0>)\n",
      "-0.7820260217140803\n",
      "cur_y: 17.366772\n",
      "tensor([0.1765], grad_fn=<PowBackward0>)\n",
      "-0.7652438537147384\n",
      "cur_y: 17.149266\n",
      "tensor([0.4678], grad_fn=<PowBackward0>)\n",
      "-0.7627880847033762\n",
      "cur_y: 17.064231\n",
      "tensor([0.5955], grad_fn=<PowBackward0>)\n",
      "-0.7623831304897438\n",
      "cur_y: 19.052142\n",
      "tensor([1.4922], grad_fn=<PowBackward0>)\n",
      "-0.7394433484534646\n",
      "cur_y: 17.754618\n",
      "tensor([0.0199], grad_fn=<PowBackward0>)\n",
      "-0.71185199037265\n",
      "cur_y: 15.529984\n",
      "tensor([5.9752], grad_fn=<PowBackward0>)\n",
      "-0.6906803582823299\n",
      "cur_y: 18.068492\n",
      "tensor([0.0017], grad_fn=<PowBackward0>)\n",
      "-0.6482838328762509\n",
      "cur_y: 17.362218\n",
      "tensor([0.6105], grad_fn=<PowBackward0>)\n",
      "-0.6367417599252782\n",
      "cur_y: 19.253082\n",
      "tensor([1.1772], grad_fn=<PowBackward0>)\n",
      "-0.6125296903077573\n",
      "cur_y: 16.465743\n",
      "tensor([3.1267], grad_fn=<PowBackward0>)\n",
      "-0.581643448010525\n",
      "cur_y: 17.206297\n",
      "tensor([1.2302], grad_fn=<PowBackward0>)\n",
      "-0.5797890250771314\n",
      "cur_y: 19.009167\n",
      "tensor([0.4897], grad_fn=<PowBackward0>)\n",
      "-0.4990577782972944\n",
      "cur_y: 17.553318\n",
      "tensor([0.9732], grad_fn=<PowBackward0>)\n",
      "-0.43898759995821823\n",
      "cur_y: 18.672334\n",
      "tensor([0.0013], grad_fn=<PowBackward0>)\n",
      "-0.41859374294385765\n",
      "cur_y: 20.214937\n",
      "tensor([2.1171], grad_fn=<PowBackward0>)\n",
      "-0.4038234502439136\n",
      "cur_y: 18.782243\n",
      "tensor([0.0003], grad_fn=<PowBackward0>)\n",
      "-0.3777220788636063\n",
      "cur_y: 19.601655\n",
      "tensor([0.5306], grad_fn=<PowBackward0>)\n",
      "-0.33432828496109585\n",
      "cur_y: 19.941253\n",
      "tensor([0.8850], grad_fn=<PowBackward0>)\n",
      "-0.32473629556406225\n",
      "cur_y: 19.708207\n",
      "tensor([0.4605], grad_fn=<PowBackward0>)\n",
      "-0.3233135530572006\n",
      "cur_y: 19.204475\n",
      "tensor([0.0284], grad_fn=<PowBackward0>)\n",
      "-0.31730408739709315\n",
      "cur_y: 20.752299\n",
      "tensor([2.8778], grad_fn=<PowBackward0>)\n",
      "-0.2913087726901323\n",
      "cur_y: 19.881930\n",
      "tensor([0.5521], grad_fn=<PowBackward0>)\n",
      "-0.2675053661219305\n",
      "cur_y: 18.502337\n",
      "tensor([0.5099], grad_fn=<PowBackward0>)\n",
      "-0.2656249734856153\n",
      "cur_y: 19.826287\n",
      "tensor([0.3598], grad_fn=<PowBackward0>)\n",
      "-0.25081961939342307\n",
      "cur_y: 17.673802\n",
      "tensor([2.5664], grad_fn=<PowBackward0>)\n",
      "-0.18341359909440438\n",
      "cur_y: 20.651894\n",
      "tensor([1.3792], grad_fn=<PowBackward0>)\n",
      "-0.11711478988131543\n",
      "cur_y: 18.494680\n",
      "tensor([1.4006], grad_fn=<PowBackward0>)\n",
      "-0.05432883121438594\n",
      "cur_y: 20.234250\n",
      "tensor([0.1360], grad_fn=<PowBackward0>)\n",
      "-0.05061553284848623\n",
      "cur_y: 19.419713\n",
      "tensor([0.2101], grad_fn=<PowBackward0>)\n",
      "-0.03514436530242174\n",
      "cur_y: 18.874534\n",
      "tensor([1.1023], grad_fn=<PowBackward0>)\n",
      "0.046593843101857775\n",
      "cur_y: 19.742703\n",
      "tensor([0.1788], grad_fn=<PowBackward0>)\n",
      "0.1411741809396436\n",
      "cur_y: 21.629692\n",
      "tensor([1.4057], grad_fn=<PowBackward0>)\n",
      "0.14703801352026594\n",
      "cur_y: 22.997446\n",
      "tensor([6.4298], grad_fn=<PowBackward0>)\n",
      "0.2072043208936791\n",
      "cur_y: 20.331743\n",
      "tensor([0.0987], grad_fn=<PowBackward0>)\n",
      "0.2261691764866281\n",
      "cur_y: 19.832038\n",
      "tensor([0.7648], grad_fn=<PowBackward0>)\n",
      "0.2472141477002146\n",
      "cur_y: 19.044951\n",
      "tensor([2.9797], grad_fn=<PowBackward0>)\n",
      "0.27569436094947763\n",
      "cur_y: 20.145880\n",
      "tensor([0.5013], grad_fn=<PowBackward0>)\n",
      "0.2999855610812906\n",
      "cur_y: 20.870830\n",
      "tensor([0.0027], grad_fn=<PowBackward0>)\n",
      "0.3159913154292396\n",
      "cur_y: 21.880290\n",
      "tensor([0.8333], grad_fn=<PowBackward0>)\n",
      "0.3333515680155136\n",
      "cur_y: 22.093468\n",
      "tensor([1.1561], grad_fn=<PowBackward0>)\n",
      "0.3470961630424529\n",
      "cur_y: 20.588679\n",
      "tensor([0.2229], grad_fn=<PowBackward0>)\n",
      "0.3632307203220751\n",
      "cur_y: 21.869046\n",
      "tensor([0.5773], grad_fn=<PowBackward0>)\n",
      "0.3938086425390968\n",
      "cur_y: 22.065212\n",
      "tensor([0.7446], grad_fn=<PowBackward0>)\n",
      "0.40229840405571643\n",
      "cur_y: 22.946026\n",
      "tensor([2.9395], grad_fn=<PowBackward0>)\n",
      "0.41958582321261906\n",
      "cur_y: 20.038418\n",
      "tensor([1.5678], grad_fn=<PowBackward0>)\n",
      "0.46779057443991223\n",
      "cur_y: 21.371266\n",
      "tensor([0.0044], grad_fn=<PowBackward0>)\n",
      "0.4721455622230357\n",
      "cur_y: 20.888006\n",
      "tensor([0.3207], grad_fn=<PowBackward0>)\n",
      "0.47355519560296744\n",
      "cur_y: 20.437825\n",
      "tensor([1.0452], grad_fn=<PowBackward0>)\n",
      "0.4758540763800935\n",
      "cur_y: 22.390078\n",
      "tensor([0.8539], grad_fn=<PowBackward0>)\n",
      "0.4801320502136497\n",
      "cur_y: 21.758106\n",
      "tensor([0.0773], grad_fn=<PowBackward0>)\n",
      "0.4872651912395142\n",
      "cur_y: 20.895512\n",
      "tensor([0.3694], grad_fn=<PowBackward0>)\n",
      "0.49618258777724\n",
      "cur_y: 21.812200\n",
      "tensor([0.0796], grad_fn=<PowBackward0>)\n",
      "0.5481837285850284\n",
      "cur_y: 21.468135\n",
      "tensor([0.0474], grad_fn=<PowBackward0>)\n",
      "0.5623024972203436\n",
      "cur_y: 22.657394\n",
      "tensor([0.8634], grad_fn=<PowBackward0>)\n",
      "0.5626853428897495\n",
      "cur_y: 21.505839\n",
      "tensor([0.0512], grad_fn=<PowBackward0>)\n",
      "0.6105745590561573\n",
      "cur_y: 21.718941\n",
      "tensor([0.0248], grad_fn=<PowBackward0>)\n",
      "0.6387956555324527\n",
      "cur_y: 20.600733\n",
      "tensor([1.8528], grad_fn=<PowBackward0>)\n",
      "0.650423548597337\n",
      "cur_y: 22.147863\n",
      "tensor([0.0237], grad_fn=<PowBackward0>)\n",
      "0.6983173648263585\n",
      "cur_y: 21.152145\n",
      "tensor([0.9649], grad_fn=<PowBackward0>)\n",
      "0.7475631487599419\n",
      "cur_y: 21.939114\n",
      "tensor([0.1136], grad_fn=<PowBackward0>)\n",
      "0.775370013545666\n",
      "cur_y: 20.434829\n",
      "tensor([3.6810], grad_fn=<PowBackward0>)\n",
      "0.7842936781143227\n",
      "cur_y: 23.031755\n",
      "tensor([0.4395], grad_fn=<PowBackward0>)\n",
      "0.7915418716709971\n",
      "cur_y: 22.144442\n",
      "tensor([0.0566], grad_fn=<PowBackward0>)\n",
      "0.8289891302646956\n",
      "cur_y: 23.444705\n",
      "tensor([0.9205], grad_fn=<PowBackward0>)\n",
      "0.8563466458741995\n",
      "cur_y: 21.505442\n",
      "tensor([1.1168], grad_fn=<PowBackward0>)\n",
      "0.8962196218608008\n",
      "cur_y: 23.751403\n",
      "tensor([1.1636], grad_fn=<PowBackward0>)\n",
      "0.8976298209906547\n",
      "cur_y: 20.471831\n",
      "tensor([4.8498], grad_fn=<PowBackward0>)\n",
      "0.9549520157715299\n",
      "cur_y: 23.684405\n",
      "tensor([0.7256], grad_fn=<PowBackward0>)\n",
      "0.9745743767842044\n",
      "cur_y: 22.805414\n",
      "tensor([0.0062], grad_fn=<PowBackward0>)\n",
      "1.0192851806190946\n",
      "cur_y: 21.950383\n",
      "tensor([1.1216], grad_fn=<PowBackward0>)\n",
      "1.04529725131788\n",
      "cur_y: 24.071290\n",
      "tensor([0.9908], grad_fn=<PowBackward0>)\n",
      "1.1093296120190033\n",
      "cur_y: 24.238506\n",
      "tensor([0.9594], grad_fn=<PowBackward0>)\n",
      "1.1179712614560662\n",
      "cur_y: 23.967632\n",
      "tensor([0.4670], grad_fn=<PowBackward0>)\n",
      "1.1385484654142177\n",
      "cur_y: 23.228061\n",
      "tensor([0.0143], grad_fn=<PowBackward0>)\n",
      "1.1490402420918309\n",
      "cur_y: 23.447121\n",
      "tensor([0.0044], grad_fn=<PowBackward0>)\n",
      "1.1637620113281597\n",
      "cur_y: 22.234547\n",
      "tensor([1.4199], grad_fn=<PowBackward0>)\n",
      "1.1700102983888094\n",
      "cur_y: 25.983397\n",
      "tensor([6.4642], grad_fn=<PowBackward0>)\n",
      "1.2330048017333424\n",
      "cur_y: 22.024424\n",
      "tensor([2.5947], grad_fn=<PowBackward0>)\n",
      "1.8243709483267654\n",
      "cur_y: 26.636334\n",
      "tensor([1.5866], grad_fn=<PowBackward0>)\n",
      "-2.187948018453601\n",
      "cur_y: 14.641382\n",
      "tensor([1.1836], grad_fn=<PowBackward0>)\n",
      "-1.7405125508198236\n",
      "cur_y: 13.517009\n",
      "tensor([1.8534], grad_fn=<PowBackward0>)\n",
      "-1.6161050508794292\n",
      "cur_y: 14.206617\n",
      "tensor([1.0670], grad_fn=<PowBackward0>)\n",
      "-1.539434640381596\n",
      "cur_y: 15.724416\n",
      "tensor([0.0732], grad_fn=<PowBackward0>)\n",
      "-1.531441246260783\n",
      "cur_y: 16.121308\n",
      "tensor([0.4260], grad_fn=<PowBackward0>)\n",
      "-1.4537666913906526\n",
      "cur_y: 15.134126\n",
      "tensor([0.3152], grad_fn=<PowBackward0>)\n",
      "-1.4173733580852041\n",
      "cur_y: 16.818831\n",
      "tensor([1.0439], grad_fn=<PowBackward0>)\n",
      "-1.4095521638417208\n",
      "cur_y: 15.819145\n",
      "tensor([2.4462e-06], grad_fn=<PowBackward0>)\n",
      "-1.31428470331877\n",
      "cur_y: 17.836585\n",
      "tensor([3.0002], grad_fn=<PowBackward0>)\n",
      "-1.301434359224939\n",
      "cur_y: 16.280937\n",
      "tensor([0.0165], grad_fn=<PowBackward0>)\n",
      "-1.1223677165321995\n",
      "cur_y: 18.041495\n",
      "tensor([1.8172], grad_fn=<PowBackward0>)\n",
      "-1.0641820967729545\n",
      "cur_y: 16.927835\n",
      "tensor([0.0023], grad_fn=<PowBackward0>)\n",
      "-1.0413133304271038\n",
      "cur_y: 17.663022\n",
      "tensor([0.4944], grad_fn=<PowBackward0>)\n",
      "-0.9962885940327544\n",
      "cur_y: 18.278264\n",
      "tensor([1.3724], grad_fn=<PowBackward0>)\n",
      "-0.9567895764979094\n",
      "cur_y: 17.492740\n",
      "tensor([0.0639], grad_fn=<PowBackward0>)\n",
      "-0.9042935499967484\n",
      "cur_y: 17.285951\n",
      "tensor([0.0154], grad_fn=<PowBackward0>)\n",
      "-0.898345171592157\n",
      "cur_y: 15.501333\n",
      "tensor([3.7622], grad_fn=<PowBackward0>)\n",
      "-0.8783769844499809\n",
      "cur_y: 17.131412\n",
      "tensor([0.1392], grad_fn=<PowBackward0>)\n",
      "-0.8447970382011947\n",
      "cur_y: 16.154646\n",
      "tensor([2.1062], grad_fn=<PowBackward0>)\n",
      "-0.7975396113765533\n",
      "cur_y: 18.603460\n",
      "tensor([0.7422], grad_fn=<PowBackward0>)\n",
      "-0.78700806407284\n",
      "cur_y: 17.055384\n",
      "tensor([0.5160], grad_fn=<PowBackward0>)\n",
      "-0.7820260217140803\n",
      "cur_y: 17.366772\n",
      "tensor([0.1765], grad_fn=<PowBackward0>)\n",
      "-0.7652438537147384\n",
      "cur_y: 17.149266\n",
      "tensor([0.4678], grad_fn=<PowBackward0>)\n",
      "-0.7627880847033762\n",
      "cur_y: 17.064231\n",
      "tensor([0.5955], grad_fn=<PowBackward0>)\n",
      "-0.7623831304897438\n",
      "cur_y: 19.052142\n",
      "tensor([1.4922], grad_fn=<PowBackward0>)\n",
      "-0.7394433484534646\n",
      "cur_y: 17.754618\n",
      "tensor([0.0199], grad_fn=<PowBackward0>)\n",
      "-0.71185199037265\n",
      "cur_y: 15.529984\n",
      "tensor([5.9752], grad_fn=<PowBackward0>)\n",
      "-0.6906803582823299\n",
      "cur_y: 18.068492\n",
      "tensor([0.0017], grad_fn=<PowBackward0>)\n",
      "-0.6482838328762509\n",
      "cur_y: 17.362218\n",
      "tensor([0.6105], grad_fn=<PowBackward0>)\n",
      "-0.6367417599252782\n",
      "cur_y: 19.253082\n",
      "tensor([1.1772], grad_fn=<PowBackward0>)\n",
      "-0.6125296903077573\n",
      "cur_y: 16.465743\n",
      "tensor([3.1267], grad_fn=<PowBackward0>)\n",
      "-0.581643448010525\n",
      "cur_y: 17.206297\n",
      "tensor([1.2302], grad_fn=<PowBackward0>)\n",
      "-0.5797890250771314\n",
      "cur_y: 19.009167\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([0.4897], grad_fn=<PowBackward0>)\n",
      "-0.4990577782972944\n",
      "cur_y: 17.553318\n",
      "tensor([0.9732], grad_fn=<PowBackward0>)\n",
      "-0.43898759995821823\n",
      "cur_y: 18.672334\n",
      "tensor([0.0013], grad_fn=<PowBackward0>)\n",
      "-0.41859374294385765\n",
      "cur_y: 20.214937\n",
      "tensor([2.1171], grad_fn=<PowBackward0>)\n",
      "-0.4038234502439136\n",
      "cur_y: 18.782243\n",
      "tensor([0.0003], grad_fn=<PowBackward0>)\n",
      "-0.3777220788636063\n",
      "cur_y: 19.601655\n",
      "tensor([0.5306], grad_fn=<PowBackward0>)\n",
      "-0.33432828496109585\n",
      "cur_y: 19.941253\n",
      "tensor([0.8850], grad_fn=<PowBackward0>)\n",
      "-0.32473629556406225\n",
      "cur_y: 19.708207\n",
      "tensor([0.4605], grad_fn=<PowBackward0>)\n",
      "-0.3233135530572006\n",
      "cur_y: 19.204475\n",
      "tensor([0.0284], grad_fn=<PowBackward0>)\n",
      "-0.31730408739709315\n",
      "cur_y: 20.752299\n",
      "tensor([2.8778], grad_fn=<PowBackward0>)\n",
      "-0.2913087726901323\n",
      "cur_y: 19.881930\n",
      "tensor([0.5521], grad_fn=<PowBackward0>)\n",
      "-0.2675053661219305\n",
      "cur_y: 18.502337\n",
      "tensor([0.5099], grad_fn=<PowBackward0>)\n",
      "-0.2656249734856153\n",
      "cur_y: 19.826287\n",
      "tensor([0.3598], grad_fn=<PowBackward0>)\n",
      "-0.25081961939342307\n",
      "cur_y: 17.673802\n",
      "tensor([2.5664], grad_fn=<PowBackward0>)\n",
      "-0.18341359909440438\n",
      "cur_y: 20.651894\n",
      "tensor([1.3792], grad_fn=<PowBackward0>)\n",
      "-0.11711478988131543\n",
      "cur_y: 18.494680\n",
      "tensor([1.4006], grad_fn=<PowBackward0>)\n",
      "-0.05432883121438594\n",
      "cur_y: 20.234250\n",
      "tensor([0.1360], grad_fn=<PowBackward0>)\n",
      "-0.05061553284848623\n",
      "cur_y: 19.419713\n",
      "tensor([0.2101], grad_fn=<PowBackward0>)\n",
      "-0.03514436530242174\n",
      "cur_y: 18.874534\n",
      "tensor([1.1023], grad_fn=<PowBackward0>)\n",
      "0.046593843101857775\n",
      "cur_y: 19.742703\n",
      "tensor([0.1788], grad_fn=<PowBackward0>)\n",
      "0.1411741809396436\n",
      "cur_y: 21.629692\n",
      "tensor([1.4057], grad_fn=<PowBackward0>)\n",
      "0.14703801352026594\n",
      "cur_y: 22.997446\n",
      "tensor([6.4298], grad_fn=<PowBackward0>)\n",
      "0.2072043208936791\n",
      "cur_y: 20.331743\n",
      "tensor([0.0987], grad_fn=<PowBackward0>)\n",
      "0.2261691764866281\n",
      "cur_y: 19.832038\n",
      "tensor([0.7648], grad_fn=<PowBackward0>)\n",
      "0.2472141477002146\n",
      "cur_y: 19.044951\n",
      "tensor([2.9797], grad_fn=<PowBackward0>)\n",
      "0.27569436094947763\n",
      "cur_y: 20.145880\n",
      "tensor([0.5013], grad_fn=<PowBackward0>)\n",
      "0.2999855610812906\n",
      "cur_y: 20.870830\n",
      "tensor([0.0027], grad_fn=<PowBackward0>)\n",
      "0.3159913154292396\n",
      "cur_y: 21.880290\n",
      "tensor([0.8333], grad_fn=<PowBackward0>)\n",
      "0.3333515680155136\n",
      "cur_y: 22.093468\n",
      "tensor([1.1561], grad_fn=<PowBackward0>)\n",
      "0.3470961630424529\n",
      "cur_y: 20.588679\n",
      "tensor([0.2229], grad_fn=<PowBackward0>)\n",
      "0.3632307203220751\n",
      "cur_y: 21.869046\n",
      "tensor([0.5773], grad_fn=<PowBackward0>)\n",
      "0.3938086425390968\n",
      "cur_y: 22.065212\n",
      "tensor([0.7446], grad_fn=<PowBackward0>)\n",
      "0.40229840405571643\n",
      "cur_y: 22.946026\n",
      "tensor([2.9395], grad_fn=<PowBackward0>)\n",
      "0.41958582321261906\n",
      "cur_y: 20.038418\n",
      "tensor([1.5678], grad_fn=<PowBackward0>)\n",
      "0.46779057443991223\n",
      "cur_y: 21.371266\n",
      "tensor([0.0044], grad_fn=<PowBackward0>)\n",
      "0.4721455622230357\n",
      "cur_y: 20.888006\n",
      "tensor([0.3207], grad_fn=<PowBackward0>)\n",
      "0.47355519560296744\n",
      "cur_y: 20.437825\n",
      "tensor([1.0452], grad_fn=<PowBackward0>)\n",
      "0.4758540763800935\n",
      "cur_y: 22.390078\n",
      "tensor([0.8539], grad_fn=<PowBackward0>)\n",
      "0.4801320502136497\n",
      "cur_y: 21.758106\n",
      "tensor([0.0773], grad_fn=<PowBackward0>)\n",
      "0.4872651912395142\n",
      "cur_y: 20.895512\n",
      "tensor([0.3694], grad_fn=<PowBackward0>)\n",
      "0.49618258777724\n",
      "cur_y: 21.812200\n",
      "tensor([0.0796], grad_fn=<PowBackward0>)\n",
      "0.5481837285850284\n",
      "cur_y: 21.468135\n",
      "tensor([0.0474], grad_fn=<PowBackward0>)\n",
      "0.5623024972203436\n",
      "cur_y: 22.657394\n",
      "tensor([0.8634], grad_fn=<PowBackward0>)\n",
      "0.5626853428897495\n",
      "cur_y: 21.505839\n",
      "tensor([0.0512], grad_fn=<PowBackward0>)\n",
      "0.6105745590561573\n",
      "cur_y: 21.718941\n",
      "tensor([0.0248], grad_fn=<PowBackward0>)\n",
      "0.6387956555324527\n",
      "cur_y: 20.600733\n",
      "tensor([1.8528], grad_fn=<PowBackward0>)\n",
      "0.650423548597337\n",
      "cur_y: 22.147863\n",
      "tensor([0.0237], grad_fn=<PowBackward0>)\n",
      "0.6983173648263585\n",
      "cur_y: 21.152145\n",
      "tensor([0.9649], grad_fn=<PowBackward0>)\n",
      "0.7475631487599419\n",
      "cur_y: 21.939114\n",
      "tensor([0.1136], grad_fn=<PowBackward0>)\n",
      "0.775370013545666\n",
      "cur_y: 20.434829\n",
      "tensor([3.6810], grad_fn=<PowBackward0>)\n",
      "0.7842936781143227\n",
      "cur_y: 23.031755\n",
      "tensor([0.4395], grad_fn=<PowBackward0>)\n",
      "0.7915418716709971\n",
      "cur_y: 22.144442\n",
      "tensor([0.0566], grad_fn=<PowBackward0>)\n",
      "0.8289891302646956\n",
      "cur_y: 23.444705\n",
      "tensor([0.9205], grad_fn=<PowBackward0>)\n",
      "0.8563466458741995\n",
      "cur_y: 21.505442\n",
      "tensor([1.1168], grad_fn=<PowBackward0>)\n",
      "0.8962196218608008\n",
      "cur_y: 23.751403\n",
      "tensor([1.1636], grad_fn=<PowBackward0>)\n",
      "0.8976298209906547\n",
      "cur_y: 20.471831\n",
      "tensor([4.8498], grad_fn=<PowBackward0>)\n",
      "0.9549520157715299\n",
      "cur_y: 23.684405\n",
      "tensor([0.7256], grad_fn=<PowBackward0>)\n",
      "0.9745743767842044\n",
      "cur_y: 22.805414\n",
      "tensor([0.0062], grad_fn=<PowBackward0>)\n",
      "1.0192851806190946\n",
      "cur_y: 21.950383\n",
      "tensor([1.1216], grad_fn=<PowBackward0>)\n",
      "1.04529725131788\n",
      "cur_y: 24.071290\n",
      "tensor([0.9908], grad_fn=<PowBackward0>)\n",
      "1.1093296120190033\n",
      "cur_y: 24.238506\n",
      "tensor([0.9594], grad_fn=<PowBackward0>)\n",
      "1.1179712614560662\n",
      "cur_y: 23.967632\n",
      "tensor([0.4670], grad_fn=<PowBackward0>)\n",
      "1.1385484654142177\n",
      "cur_y: 23.228061\n",
      "tensor([0.0143], grad_fn=<PowBackward0>)\n",
      "1.1490402420918309\n",
      "cur_y: 23.447121\n",
      "tensor([0.0044], grad_fn=<PowBackward0>)\n",
      "1.1637620113281597\n",
      "cur_y: 22.234547\n",
      "tensor([1.4199], grad_fn=<PowBackward0>)\n",
      "1.1700102983888094\n",
      "cur_y: 25.983397\n",
      "tensor([6.4642], grad_fn=<PowBackward0>)\n",
      "1.2330048017333424\n",
      "cur_y: 22.024424\n",
      "tensor([2.5947], grad_fn=<PowBackward0>)\n",
      "1.8243709483267654\n",
      "cur_y: 26.636334\n",
      "tensor([1.5866], grad_fn=<PowBackward0>)\n",
      "Finished Training\n",
      "a : Parameter containing:\n",
      "tensor([2.9495], requires_grad=True)\n",
      "b : Parameter containing:\n",
      "tensor([20.0068], requires_grad=True)\n"
     ]
    }
   ],
   "source": [
    "for epoch in range(2):  # loop over the dataset multiple times\n",
    "\n",
    "    running_loss = 0.0\n",
    "    for i, data in enumerate(input_list):\n",
    "        cur_x = data\n",
    "        print(cur_x)\n",
    "        cur_y = output_list[i]\n",
    "        print(\"cur_y: %f\" % cur_y)\n",
    "\n",
    "\n",
    "        # zero the parameter gradients\n",
    "        opt_fn.zero_grad()\n",
    "\n",
    "        # forward + backward + optimize\n",
    "        output = test_run(torch.tensor(cur_x))\n",
    "        loss = torch.pow(output - torch.tensor(cur_y), 2)\n",
    "        print(loss)\n",
    "        loss.backward()\n",
    "        opt_fn.step()\n",
    "\n",
    "        # print statistics\n",
    "        running_loss += loss\n",
    "        if i % 2000 == 1999:    # print every 2000 mini-batches\n",
    "            print('[%d, %5d] loss: %.3f' %\n",
    "                  (epoch + 1, i + 1, running_loss / 2000))\n",
    "            running_loss = 0.0\n",
    "\n",
    "print('Finished Training')\n",
    "for name,parameters in test_run.named_parameters():\n",
    "    print(name,':',parameters)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "mx_py3",
   "language": "python",
   "name": "mx_py3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
